# DeerFlow 与 DB-GPT：从界面到代码，理解两个项目

本文对比的是这次实际使用的源码：DeerFlow `a58ab484a641fd5928ae512ad21c5c7fd7a18c18`，DB-GPT `ca9f014cb3ead157ca2ee6ce645658f5fb55138c`（0.8.2）及本项目的电商增强。框架有某项能力，不等于本服务器已配置、测试了该能力。

## 1. 先把三个层次分清

你看到的网页是操作入口，真正决定分析如何执行的是后端。当前仓库里还有适合 GitHub Pages 的浏览器演示版，它不能代表官方完整版的全部能力。

| 层次 | DeerFlow | DB-GPT |
|---|---|---|
| 官方完整平台 | Next.js 前端、Gateway、Agent 运行时、沙箱、会话持久化 | 官方前端、Python 服务、模型适配、数据源、Agent、AWEL 等模块 |
| 我们当前的工程工作 | 部署、模型配置、登录、资源限制、沙箱适配、产物下载验证 | 除完整平台部署外，增加电商数据、SQL 核验、贡献分解、报告证据与工具集成 |
| GitHub Pages 演示 | `deerflow-web`：浏览器对话及文本检索 | `db-gpt-commerce/web`：浏览器 SQLite 分析与 DeepSeek SQL 生成 |

Pages 只托管静态文件；官方 Python 后端、后台任务和沙箱要运行在服务器。前端托管和后端托管可以分开，但此次完整版直接在服务器提供官方界面，更容易保持官方接口路径一致。

## 2. 最重要的区别：怎样决定下一步，以及怎样判定结果正确

**DeerFlow 的重心是完成开放式任务。**例如“研究某个行业，收集资料，做一个报告”：任务的步骤事先不完全确定。Lead Agent 读取用户要求和工具描述，决定搜索、读文件、执行代码，或派发子任务；看到工具结果后，再决定下一步。工程重点在任务状态、上下文、工具执行、子任务协调和中断恢复。

**DB-GPT 的重心是围绕数据构建应用。**官方平台提供数据连接、模型接口、数据相关 Agent 与工作流等基础设施。但单独安装平台，并不会自动知道企业的收入定义，也不会自动得到本项目的独立校验和贡献分解。

**我们写的电商模块把一个业务问题做得更确定。**外层 Agent 可以决定调用哪个工具；进入 `analyze_commerce_revenue` 后，必须依次通过既定口径、SQL 核验和计算规则。模型不能自行跳过核验后宣布成功。

两者的能力有重叠：DeerFlow 可以分析数据，DB-GPT 也有 ReAct Agent。区别不是“一个能用工具、另一个不能”，而是平台关注的对象，以及我们在业务层增加了什么约束。

## 3. DeerFlow：一次请求从哪里开始，到哪里结束

```text
浏览器里的用户消息
  → Nginx：把页面请求和 API 请求转发到不同服务
  → Gateway：检查身份，管理会话与运行请求
  → RunManager：管理本次运行的生命周期
  → run_agent：调用组装好的 Lead Agent 图
  → Lead Agent：模型 → 工具 → 工具结果 → 模型，循环决策
       ├─ 文件/代码工具 → AIO 沙箱 → 文件或执行结果
       ├─ task 工具 → 子 Agent → 子任务结果
       └─ Skills / 记忆 / 中间件 → 提供约束与上下文
  → StreamBridge：把运行事件转换成前端可消费的流
  → 前端显示文字、工具进度、文件与下载入口
```

这份源码将 Agent 运行时嵌在 Gateway 中。不要照搬旧版本文章，误以为一定要额外启动一个独立 LangGraph Server。

### Lead Agent 到底是什么

它是一个被组装出来的决策循环，不是单纯的一段提示词。`backend/packages/harness/deerflow/agents/lead_agent/agent.py` 负责组合模型、系统提示、工具、状态结构和中间件，调用 LangChain 的 `create_agent`。模型提出工具调用后，运行时执行工具，再将结果加入状态，继续下一轮。

### 中间件为什么重要

中间件负责横跨多个步骤的规则，例如消息压缩、记忆注入、待办状态、工具异常处理、子 Agent 数量限制、循环检测和最终回复处理。它们不是额外的“专家模型”，而是围绕 Agent 循环工作的程序组件。具体装配由源码和配置决定，不能把所有可选能力都说成已启用。

### 子 Agent 和沙箱有什么区别

子 Agent 是另一个执行子任务的模型循环；沙箱是代码和工具实际运行的环境。子 Agent 可以使用沙箱，主 Agent 也可以使用沙箱。把任务拆给三个子 Agent，不意味着一定会有三个独立服务器。

本服务器为了内存控制，子 Agent 并发限制为 1，模型并发限制为 2。因此可以讲“支持子任务委派”，但不应把默认并发或多 Agent 性能提升写成这台服务器的实测结果。

### 会话保存为什么不等于答案可复现

保存消息、工具记录和运行状态，有助于继续任务及排查过程；但数据源可能变化、工具可能有副作用、模型也可能给出不同输出。要复算某个金额，还需要冻结数据范围、保留 SQL 和参数，并固定计算规则。这恰好是电商模块专门补上的部分。

## 4. DB-GPT：外层 Agent 加内层业务工作流

```text
官方前端提交问题
  → 官方 /api/v1/chat/react-agent 接口
  → ReAct Agent 看见已注册的业务工具描述
  → 调用 analyze_commerce_revenue(region, as_of)
  → commerce/workflow.py：run_analysis
       1. resolve：确定地区、两个月份及支持范围
       2. sql_stage：真实模型生成 SQL；基准模式使用标准 SQL
       3. verification：只读执行 + 独立 Python 明细核对
       4. calculation：精确计算各因素的贡献
  → DAG 完成后保存 SQL、参数、证据和 HTML 报告
  → 官方 html_interpreter 读取生成好的报告文件
  → 用户看到结果，并可下载证据
```

这里有两个完全不同的编排层。外层 ReAct 负责对话和工具选择，路径可变；内层 AWEL DAG 是明确的四节点串行图，规则由我们写死在代码里。报告保存发生在 DAG 返回之后，不应把它包装成第五个 AWEL 节点。

`run_official.py` 是启动适配入口。它先载入环境和持久化加密密钥，准备官方工作目录，再通过 `official_integration.install()` 把电商工具、数据源和报告下载路由注册进官方服务。我们没有重写官方前端。

## 5. 用同一个问题比较两条执行路径

问题：“上个月华东收入下降了，拆解订单量、客单价、退款和渠道结构，并提供依据。”

在通用 DeerFlow 中，Agent 可以先检查你提供的文件或数据接口，然后编写 SQL / Python、执行和整理报告。流程灵活，但业务口径与核验规则需要通过数据说明、工具或技能补充。不能仅凭最后出现了一张漂亮图表，就判断结果正确。

在电商 DB-GPT 模块中，进入业务工具后会做以下约束：

1. **时间先确定。**演示数据覆盖 2026 年 6—8 月。默认基准日为 2026-09-16，“上个月”就是 8 月，对比 7 月。现在是 10 月也不会自动把样本变成真实 9 月经营数据。指定超出支持范围的日期应被拒绝。
2. **金额先定义。**净收入 = 当月支付订单实付金额 − 当月成功退款。订单按 `paid_at`，退款按 `refunded_at`；地区取订单的收货地区快照，而不是用户现在所在地区。
3. **避免一对多重复计数。**一个订单如果有两个明细和两次退款，直接把三表相连可能产生四行。应分别聚合支付与退款，再按月份和渠道连接。
4. **SQL 能运行还不够。**模型可能写出合法但口径错误的 SQL。程序另用 Python 遍历原始订单和退款，以不同实现计算基准结果，逐项核对六行“月份 × 渠道”结果。
5. **核验失败不能掩盖。**被拒绝的模型 SQL 最多进行一次修复；仍失败则保存失败证据并返回失败。不能偷偷切换标准 SQL，却说是模型成功完成。
6. **通过后再做贡献计算。**模型不负责心算贡献金额；代码使用精确分数计算，并检查贡献合计是否等于总变化。

这是“模型提出候选计算方案，代码决定是否接受”的逻辑。当前的核验器适用于这个限定数据任务，不等于能验证任意 SQL 的全部业务含义。

## 6. 客单价和渠道结构为什么不能重复解释

净收入写成：`R = N × Σ(s_c × p_c) − F`。

`N` 是支付订单总量，`s_c` 是渠道订单占比，`p_c` 是该渠道的实付客单价，`F` 是成功退款。总体客单价本来就是各渠道客单价的加权平均，既受渠道价格影响，也受渠道占比影响。因此不能先拿总体客单价解释全部变化，再把渠道结构额外加一遍。

我们把 N、渠道占比向量、渠道内客单价向量视为三个因素。三个因素有六种替换顺序，代码计算每种顺序的边际变化，再取平均，分配它们的交互影响；退款作为减项单独计算。金额底层使用整数分和 `Fraction`，展示时才换算成人民币元。

固定样本的 99,000 元下降分成：订单量 −44,800 元、渠道结构 −32,775 元、渠道内客单价 −13,425 元、退款 −8,000 元。四项相加正好等于 −99,000 元。

这些是**算术贡献**。它说明账面的变化来自哪些变量，不证明广告投放、竞争对手或产品质量导致了变化。业务原因仍需实验、活动记录、客群等额外证据。

## 7. 按什么顺序看代码，才不会迷路

| 阅读顺序 | 文件或目录 | 带着什么问题读 |
|---|---|---|
| 1 | `commerce/data.py` | 数据到底长什么样？时间、地区、退款怎样归属？ |
| 2 | `commerce/query.py` | 标准 SQL 是什么？哪些查询不允许执行？ |
| 3 | `commerce/workflow.py` | 状态怎么在四个节点间传递？失败走哪里？ |
| 4 | `commerce/analysis.py` | 六种替换顺序怎样计算？为何不会重复归因？ |
| 5 | `commerce/report.py` | 报告数字从哪里来？保留了哪些证据？ |
| 6 | `commerce/official_integration.py` | 官方 Agent 怎样找到我们的工具？ |
| 7 | `run_official.py` 与 `official.toml` | 官方服务如何启动，数据保存到哪里？ |
| 8 | DeerFlow `runtime/` 与 `agents/lead_agent/agent.py` | 通用 Agent 的循环和状态如何组织？ |
| 9 | DeerFlow `subagents/executor.py` 与 `community/aio_sandbox/backend.py` | 委派如何执行？工具究竟在哪里运行？ |

DeerFlow 的上述路径相对于 `backend/packages/harness/deerflow/`。DB-GPT 官方 ReAct 接口在 `packages/dbgpt-app/src/dbgpt_app/openapi/api_v1/agentic_data_api.py`。不要从一个数千行的 Agent 文件顺着读到末尾；先沿着一条真实请求追踪调用关系。

## 8. 这个项目现在算完整吗

对于“固定模拟数据上的地区月度收入分析”，已有数据、模型 SQL、校验、计算、报告和复算链路，是可演示、可阅读代码的完整闭环。官方平台已提供成熟界面，但这不等于企业生产系统已经完成。

目前不能据此声称：已接入真实企业数据库、任意指标都能正确回答、多租户权限完善、完成高并发压测、具备完整运维告警，或已经验证所有知识库和本地模型功能。尤其这台服务器只有约 1.6 GB 内存，适合作品演示；同时运行复杂沙箱和多个分析任务时，性能仍需单独测试。

现有证据包含 SQL、参数、数据指纹和源码指纹。证据包没有自动附带整份数据库；换机器复算仍需保留相同数据库快照。模型调用再次运行也不保证得到相同 SQL；我们保证的是保存下来的 SQL 和计算规则在相同数据上可以复核。

## 9. 面试或答辩可以怎样讲

“DeerFlow 让我理解通用 Agent 怎么管理任务、上下文、工具和沙箱；DB-GPT 电商项目让我把一个具体业务分析做成可验证的计算链路。前者的主要工程难点是让长任务执行下去，后者的主要业务难点是让金额口径一致、SQL 不重复计数、贡献能对账。我的新增部分是电商数据与边界样本、独立校验器、精确贡献分解、证据报告，以及把这个业务工具接入官方平台。”

如果进一步问两个项目能否组合：可以让 DeerFlow 做研究与任务调度，再调用 DB-GPT 的受控分析接口，把可信计算结果作为报告依据。但当前没有实现这条跨平台调用链，不能将设计设想写成已完成能力。先把两个独立项目部署和验证清楚，比画一张已经互联但实际上没有接口的图更有价值。

## 10. 同一台小服务器上的真实工程问题

界面由浏览器显示，不代表后台很轻。官方 DB-GPT 会预热 Lyric 代码执行进程；本次观察到两组 Python worker，每组约二百多 MiB，即使电商分析只用 SQLite 和 Python 业务函数，也会承担这部分常驻开销。

因此新增了云端可选适配 `commerce/cloud_runtime.py`：只跳过启动预热，保留官方 `_ensure_initialized`，首次真正执行代码时再初始化。专用分析、DeepSeek SQL 与报告照常工作。测试验证了启动时不创建 worker、首次执行时创建、后续执行不重复创建，以及正常关闭。该模式由服务器环境变量显式开启，原本地启动默认不变。

另一项适配是报告地址使用相对路径或配置的公网 origin，避免云端回复中出现开发机地址；无 Git 元数据的源码发布包通过打包时保存的 `UPSTREAM_COMMIT` 保留官方版本来源，避免错误地记录外层业务仓库提交。

这些改动与业务贡献算法处于不同层：前者解决部署和运行资源，后者解决结果正确性。介绍项目时应分别讲清，不能把部署成功说成算法正确，也不能把算对一个样例说成服务可以承担高并发。
